package com.ido.dingding;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ido.dingding.domain.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;

/**
 * 钉钉消息发送模版
 **/
@Slf4j
@Component
public class DingdingTemplate {

    private static DingDingConfig config;

    @Autowired
    private DingDingConfig dingDingConfig;

    @PostConstruct
    private void init() {
        config = dingDingConfig;
    }

    /**
     * 发送文本消息
     * @param text
     * @return
     */
    public boolean sendTextMessage(TextMsg text) {
        return sendMsg(text.getJSONString());
    }

    /**
     * 发送链接消息
     * @param linkMsg
     * @return
     */
    public boolean sendLinkMessage(LinkMsg linkMsg) {
        return sendMsg(JSON.toJSONString(linkMsg));
    }

    /**
     * 发送markdown消息
     */
    public boolean sendMarkdownMessage(MarkdownMsg markdownMsg) {
        return sendMsg(markdownMsg.getJSONString());
    }

    /**
     * 发送Card消息
     * @param actionCardMsg
     * @return
     */
    public boolean sendActionCardMessage(ActionCardMsg actionCardMsg) {
        return sendMsg(JSON.toJSONString(actionCardMsg));
    }

    /**
     * 发送FeedCard消息
     * @param feedCardMsg
     * @return
     */
    public boolean sendFeedCardMessage(FeedCardMsg feedCardMsg) {
        return sendMsg(feedCardMsg.getJSONString());
    }

    /**
     * 发送消息
     * @param jsonString 消息内容
     * @return
     */
    public static boolean sendMsg(String jsonString) {
        try {
            log.info("【钉钉】发送消息 body: {}", jsonString);
            String webUrl = singKey(config.getWebhook(), config.getSecret());
            String result = HttpUtil.post(webUrl, jsonString);
            log.info("【钉钉】发送消息: {}", result);
            JSONObject jt = JSONObject.parseObject(result);
            return jt.getIntValue("errcode") == 0;
        } catch (Exception e) {
            log.info("【钉钉】发送消息异常，e={}", e.getMessage());
            return false;
        }
    }

    /**
     * 加密安全验证
     *
     * @return
     * @throws Exception
     */
    private static String singKey(String webhook, String secret) throws Exception {
        Long timestamp = System.currentTimeMillis();
        String stringToSign = timestamp + "\n" + secret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
        String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
        return String.format("%s&timestamp=%s&sign=%s", webhook, timestamp, sign);
    }

}

